
#include <stdint.h>
#include <stdio.h>

#include "hpm_clock_drv.h"

#include "jtag.h"
#include "riscv_debug.h"
#include "target.h"

target_t target_riscv;
char w_mem[32];
char r_mem[32];

void test(void)
{
//  init test
    target_riscv_init(&target_riscv);
    target_riscv.target_init();
    if (irlen != 5)
    {
        RISCV_DEBUG_LOG_DBG("ERR: irlen = 0x%x \n", irlen);
        return;
    }
    if (tapnum != 1)
    {
        RISCV_DEBUG_LOG_DBG("ERR: tapnum = 0x%x \n", tapnum);
        return;
    }
    if (idcode != 0x1000563D)
    {
        RISCV_DEBUG_LOG_DBG("ERR: idcode = 0x%x \n", idcode);
        return;
    }
    target_riscv.idcode = idcode;
//  memory access test
    for (int i = 0; i < 32; i++)
    {
        w_mem[i] = i + 2;
    }
    if (!target_riscv.target_write_mem(0x3, w_mem, 32))
    {
        if (!target_riscv.target_read_mem(0x3, r_mem, 32))
        {
            for (int i = 0; i < 32; i++)
            {
                if (w_mem[i] != r_mem[i])
                {
                    RISCV_DEBUG_LOG_DBG("write/read memory err! \n");
                    goto err;
                }
            }
        }
    }
//  bkt resume test
//  led main fun(0x80005ae4)
    uint32_t PC = 0x80005ae4;
    uint32_t PC2 = 0;
    uint32_t PC3 = 0;
    uint32_t PC4 = 0;
    int reason = -1;
    int reason2 = -1;
    int stat = -1;

    uint32_t rst;
    riscv_dmcontrol_t dmcontrol;
    riscv_dmstatus_t dmstatus;

    dmcontrol.reg = 0;
    riscv_dmi_read(RISCV_DM_CONTROL, &dmcontrol.reg, &rst);
    asm volatile("ebreak");
    dmstatus.reg = 0;
    riscv_dmi_read(RISCV_DM_STATUS, &dmstatus.reg, &rst);
    asm volatile("ebreak");

    target_riscv.target_read_reg(&PC2, 32, 4);
    stat = target_riscv.target_resume(NULL, 0);
    asm volatile("ebreak");
    target_riscv.target_halt();

    dmcontrol.reg = 0;
    riscv_dmi_read(RISCV_DM_CONTROL, &dmcontrol.reg, &rst);
    asm volatile("ebreak");
    dmstatus.reg = 0;
    riscv_dmi_read(RISCV_DM_STATUS, &dmstatus.reg, &rst);
    asm volatile("ebreak");

    reason = target_riscv.target_reset(0); // 复位
    asm volatile("ebreak");
    reason2 = target_riscv.target_reset(1); // 复位后挂起
    asm volatile("ebreak");
    target_riscv.target_read_reg(&PC3, 32, 4);
    asm volatile("ebreak");

    dmcontrol.reg = 0;
    riscv_dmi_read(RISCV_DM_CONTROL, &dmcontrol.reg, &rst);
    asm volatile("ebreak");
    dmstatus.reg = 0;
    riscv_dmi_read(RISCV_DM_STATUS, &dmstatus.reg, &rst);
    asm volatile("ebreak");

    stat = target_riscv.target_breakpiont(&PC, 0, 1); // 设置硬件断点
    asm volatile("ebreak");

    dmcontrol.reg = 0;
    riscv_dmi_read(RISCV_DM_CONTROL, &dmcontrol.reg, &rst);
    asm volatile("ebreak");
    dmstatus.reg = 0;
    riscv_dmi_read(RISCV_DM_STATUS, &dmstatus.reg, &rst);
    asm volatile("ebreak");
    stat = target_riscv.target_resume(NULL, 0);
stat = target_riscv.target_breakpiont(&PC, 0, 0); 
    stat = target_riscv.target_resume(NULL, 0);
    asm volatile("ebreak");
    asm volatile("ebreak");
    target_riscv.target_halt();
    asm volatile("ebreak");
    target_riscv.target_read_reg(&PC4, 32, 4);
    asm volatile("ebreak");
    stat = target_riscv.target_resume(NULL, 0);
    asm volatile("ebreak");
    target_riscv.target_halt();
    asm volatile("ebreak");

// step test
    
    dmcontrol.reg = 0;
    riscv_dmi_read(RISCV_DM_CONTROL, &dmcontrol.reg, &rst);
    asm volatile("ebreak");
    dmstatus.reg = 0;
    riscv_dmi_read(RISCV_DM_STATUS, &dmstatus.reg, &rst);
    asm volatile("ebreak");

    uint32_t PC5 = 0;
    uint32_t PC6 = 0;
    uint32_t PC7 = 0;
    stat = target_riscv.target_step(1); // 进入单步模式
    asm volatile("ebreak");
    stat = target_riscv.target_resume(NULL, 0);
    asm volatile("ebreak");

    dmcontrol.reg = 0;
    riscv_dmi_read(RISCV_DM_CONTROL, &dmcontrol.reg, &rst);
    asm volatile("ebreak");
    dmstatus.reg = 0;
    riscv_dmi_read(RISCV_DM_STATUS, &dmstatus.reg, &rst);
    asm volatile("ebreak");

    stat = target_riscv.target_read_reg(&PC5, 32, 4);
    asm volatile("ebreak");
    stat = target_riscv.target_resume(NULL, 0);
    asm volatile("ebreak");

    dmcontrol.reg = 0;
    riscv_dmi_read(RISCV_DM_CONTROL, &dmcontrol.reg, &rst);
    asm volatile("ebreak");
    dmstatus.reg = 0;
    riscv_dmi_read(RISCV_DM_STATUS, &dmstatus.reg, &rst);
    asm volatile("ebreak");

    stat = target_riscv.target_read_reg(&PC6, 32, 4);
    asm volatile("ebreak");
    stat = target_riscv.target_resume(NULL, 0);
    asm volatile("ebreak");
    stat = target_riscv.target_read_reg(&PC7, 32, 4);
    asm volatile("ebreak");
    stat = target_riscv.target_step(0); // 退出单步模式
    stat = target_riscv.target_resume(NULL, 0);
    asm volatile("ebreak");
err:
    while (1){;}
}
